import { isImg, isVideo, uid } from '@/utils';
import { useState, useEffect } from 'react';
import classNames from 'classnames';
import React, { useRef } from 'react';
import ReactDOM from 'react-dom';
import { Form, Input, Popover } from 'antd';
import { useForm } from 'antd/lib/form/Form';
import CheckTag from '../../components/CheckTag';
import styles from './index.less';
import regMap from '@/utils/regMap';
import { message, Upload, Spin } from 'antd';
import type { RcFile, UploadFile, UploadProps } from 'antd/es/upload/interface';
import type { UploadChangeParam } from 'antd/es/upload';
import { allGet } from '@/services/pc';
import storage from '@/utils/storage';
import { USERINFO, apiUrl } from '@/common/const';

interface OriginAuthResultProps {
  container?: HTMLElement;
  visible: boolean;
  onClose?: () => void;
  destroyOnClose?: boolean;
  onClick?: () => void;
  buttonText?: string;
  title?: string;
}

const OriginAuthResult: React.FC<OriginAuthResultProps> = ({
  container = document.body,
  visible,
  onClose,
  destroyOnClose = false,
  onClick,
  buttonText = '我知道了',
  title = ' 实名认证完成',
}) => {
  if (destroyOnClose && !visible) {
    return null;
  }

  const handleClick = () => {
    onClose?.();
    onClick?.();
  };

  const content = (
    <div className={classNames(styles.authResult)} style={{ display: visible ? 'block' : 'none' }}>
      <i className={styles.mask} onClick={() => onClose?.()} />
      <div className={styles.main}>
        <i className={styles.success} />
        <div className={styles.title}>{title}</div>
        <div className={styles.rz} onClick={handleClick}>
          {buttonText}
        </div>
        <img
          loading="lazy"
          className={styles.close}
          src={require('./images/icon-close.png')}
          alt=""
          onClick={() => onClose?.()}
        />
      </div>
    </div>
  );

  return ReactDOM.createPortal(
    // 这里可以是dom元素,也可以是react组件,还可以是react节点
    content,
    // 将传入的元素/组件/节点,挂载到container下面
    container,
  );
};

const authResultshow = (
  options: Pick<OriginAuthResultProps, 'onClose' | 'onClick' | 'buttonText' | 'title'> = {} as any,
) => {
  const { onClose } = options || {};
  const container = document.createElement('div');
  container.setAttribute('id', uid() + '' + Date.now());
  document.body.appendChild(container);
  const handleClose = () => {
    onClose?.();
    ReactDOM.unmountComponentAtNode(container);
    document.body.removeChild(container);
  };
  ReactDOM.render(
    <OriginAuthResult
      {...options}
      container={container}
      visible={true}
      destroyOnClose
      onClose={handleClose}
    />,
    container,
  );
};

type AuthResultType = typeof OriginAuthResult & {
  show: typeof authResultshow;
};
export const AuthResult = OriginAuthResult as AuthResultType;
AuthResult.show = authResultshow;

const TipsPopover = (props) => {
  return (
    <div className={styles.tips} onClick={(e) => e.stopPropagation()}>
      <div className={styles.container}>
        <img loading="lazy" src={require('./images/tips-img.png')} alt="" width={221} />
        <div className={styles.text}>
          1 手持身份证照（香港，澳门，台湾证件）拍摄视频，要求本人与证件同时出镜并能看清证件上的内容
          <br />2 嘴里同时说出，此验证视频仅供CGJOY课程实名认证使用。
        </div>
      </div>
    </div>
  );
};

const UploadVideo = ({ type = 1, onChange = (fileList) => {} }) => {
  const [loading, setLoading] = useState(false);
  const [percent, setPercent] = useState<any>(0);
  const [status, setStatus] = useState('');
  const [config, setConfig] = useState<Record<string, any>>({});
  const init = async () => {
    const response = await allGet({ params: { mod: 'teacher', do: 'add', version: 'pc1.0' } });
    setConfig(response?.data?.swfconfig ?? {});
  };

  useEffect(() => {
    init();
  }, []);

  const getExtraData = (file) => {
    const userInfo = storage.get(USERINFO);
    return {
      mod: 'swfupload',
      ac: 'profile',
      uid: userInfo?.uid,
      hash: config?.hash,
      version: 'pc1.0',
      field: 'field1',
    };
  };
  const beforeUpload = async (file) => {
    const isvideo = isVideo(file.name);
    // 格式不符合
    if (!isvideo) {
      message.error('视频仅支持 avi/mp4/mov 格式');
      return Upload.LIST_IGNORE;
    }

    return file;
    // return isJpgOrPng && isLt2M;
  };
  const handleChange: UploadProps['onChange'] = (info: UploadChangeParam<UploadFile>) => {
    if (info.file.status === 'uploading') {
      setLoading(true);
      setPercent(info.file.percent?.toFixed(0));
      setStatus('uploading');
      return;
    }
    if (info.file.status === 'done') {
      onChange(info.fileList);
      setLoading(false);
      setStatus('done');
    }
    if (info.file.status === 'error') {
      message.error('上传失败');
      setLoading(false);
      setStatus('error');
    }
  };

  const props = {
    //action: 'https://www.mocky.io/v2/5cc8019d300000980a055e76' ||  OSSData.host,
    action: apiUrl,
    name: 'Filedata',
    data: getExtraData,
    listType: 'picture-card',
    className: styles.uploadVideo,
    showUploadList: false,
    beforeUpload: beforeUpload,
    onChange: handleChange,
    disabled: loading,
  };
  const text = () => {
    if (status === 'done') {
      return '已上传成功，点击可重新上传';
    }
    if (status === 'uploading') {
      return '上传中...';
    }
    if (status === 'error') {
      return '上传失败，请重新上传';
    }
    return '点击上传视频（avi/mp4/mov 格式）';
  };
  return (
    <Upload {...(props as any)}>
      <div className={classNames(styles.process, styles[status])}>
        <i className={styles.processInner} style={{ width: `${percent}%` }} />
        {text()}
        {status === 'done' && <i className={styles.icon} />}
      </div>
    </Upload>
  );
};

const getBase64 = (img: RcFile, callback: (url: string) => void) => {
  const reader = new FileReader();
  reader.addEventListener('load', () => callback(reader.result as string));
  reader.readAsDataURL(img);
};

const UploadIdCard = ({ type = 1, onChange = (fileList) => {} }) => {
  const [loading, setLoading] = useState(false);

  const [imageUrl, setImageUrl] = useState<string>();
  const [config, setConfig] = useState<Record<string, any>>({});
  const init = async () => {
    const response = await allGet({ params: { mod: 'teacher', do: 'add', version: 'pc1.0' } });
    setConfig(response?.data?.swfconfig ?? {});
  };

  useEffect(() => {
    init();
  }, []);

  const getExtraData = (file) => {
    const userInfo = storage.get(USERINFO);
    return {
      mod: 'swfupload',
      ac: 'profile',
      uid: userInfo?.uid,
      hash: config?.hash,
      version: 'pc1.0',
      field: type === 1 ? 'field3' : 'field2',
    };
  };
  const beforeUpload = async (file) => {
    const isimg = isImg(file.name);
    // 格式不符合
    if (!isimg) {
      message.error('图片仅支持 jpg/png/gif 格式');
      return Upload.LIST_IGNORE;
    }

    return file;
  };
  const handleChange: UploadProps['onChange'] = (info: UploadChangeParam<UploadFile>) => {
    if (info.file.status === 'uploading') {
      setLoading(true);
      return;
    }
    if (info.file.status === 'done') {
      getBase64(info.file.originFileObj as RcFile, (url) => {
        setLoading(false);
        setImageUrl(url);
      });
      setLoading(false);
      onChange(info.fileList);
    }
    if (info.file.status === 'error') {
      message.error(`上传${type === 1 ? '身份证正面' : '身份证反面'}失败`);
      setLoading(false);
    }
  };

  const uploadButton = (
    <Spin spinning={loading} className={styles.loading} tip="上传中">
      <div className={styles.button}>
        <i className={styles.icon} />
        {type === 1 ? '上传身份证正面照' : '上传身份证反面照'}
      </div>
    </Spin>
  );

  const props = {
    // action: 'https://www.mocky.io/v2/5cc8019d300000980a055e76' ||  OSSData.host,
    // action: OSSData.host,
    action: apiUrl,
    name: 'Filedata',
    data: getExtraData,
    listType: 'picture-card',
    className: styles.uploadIdCard,
    showUploadList: false,
    beforeUpload: beforeUpload,
    onChange: handleChange,
    disabled: loading,
  };
  return (
    <Upload {...(props as any)}>
      {!loading && imageUrl ? (
        <i className={styles.img} style={{ backgroundImage: `url(${imageUrl})` }} />
      ) : (
        uploadButton
      )}
    </Upload>
  );
};

interface OriginAuthModalProps {
  container?: HTMLElement;
  visible: boolean;
  defaultIndex?: number;
  data?: any;
  onClose?: () => void;
  onSuccess: (data, type) => Promise<any>;
  destroyOnClose?: boolean;
}

const OriginAuthModal: React.FC<OriginAuthModalProps> = ({
  type,
  container = document.body,
  visible,
  data,
  onClose,
  onSuccess,
  destroyOnClose = false,
}) => {
  const tag = [
    { label: '大陆用户', value: 1 },
    { label: '港澳台及海外用户', value: 2 },
  ];
  const [form] = useForm();

  /**
   * 轮询认证状态
   */
  const timer = useRef<any>(null);
  const pollAuthStatus = (values) => {
    timer.current = setInterval(async () => {
      const response = await allGet({
        params: {
          mod: 'train',
          do: 'verify',
          version: 'pc1.0',
          check: 1,
        },
      });
      if (response?.data?.status == 2) {
        onClose?.();
        clearInterval(timer.current);
        onSuccess?.(values, 1);
      }
    }, 2000);
  };

  const [config, setConfig] = useState<any>({});
  useEffect(() => {
    return clearInterval(timer.current);
  }, []);
  // 大陆用户
  const handleDLAuth = async (values) => {
    const response = await allGet({
      params: {
        verifysubmit: 1,
        mod: 'train',
        do: 'verify',
        version: 'pc1.0',
        cardname: values.name,
        certno: values.idcard,
        cardno: values.bankcard,
        nationality: 0,
      },
    });
    if (!response.success) {
      return false;
    }
    if (response?.data?.isverify === 1) {
      onSuccess?.(values, 1);
      onClose?.();
      return;
    }
    setConfig(response);
    setStep(2);
    pollAuthStatus(values);
    return true;
  };
  // 海外用户
  const handleHwAuth = async (values) => {
    const response = await allGet({
      params: {
        verifysubmit: 1,
        mod: 'train',
        do: 'verify',
        version: 'pc1.0',
        cardname: values.name,
        certno: values.idcard,
        field1: values?.idcardVideo?.[0]?.response?.data?.attachment,
        field2: values?.idcardBack?.[0]?.response?.data?.attachment,
        field3: values?.idcardFront?.[0]?.response?.data?.attachment,
        nationality: 1,
      },
    });
    if (!response.success) {
      message.info(response?.data || '提交失败');
      return false;
    }
    onClose?.();
    AuthResult.show({
      title: response?.data?.msg || '提交成功，请耐心等待人工审核',
    });
    return true;
  };

  const handleSuccess = async (values) => {
    if (values.type[0] === 1) {
      return await handleDLAuth(values);
    } else {
      return await handleHwAuth(values);
    }
  };

  const [submitLoading, setSubmitLoading] = useState(false);
  const handleSubmit = async () => {
    if (submitLoading === true) return;
    setSubmitLoading(true);
    try {
      const values = await form.validateFields();
      handleSuccess(values);
    } catch (error) {
      console.log(error);
    } finally {
      setSubmitLoading(false);
    }
  };

  const validUpload = (rule, value: any, type) => {
    if (!value) return Promise.reject(`请上传${type}`);

    if (Array.isArray(value)) {
      if (value.some((item) => item.status === 'uploading')) {
        return Promise.reject('还有正在上传，稍等一下');
      }
      if (value.some((item) => item.status === 'error')) {
        return Promise.reject('有上传失败，请重新上传');
      }
    }
    return Promise.resolve();
  };

  if (destroyOnClose && !visible) {
    return null;
  }
  const typeValue = Form.useWatch('type', form);

  const [step, setStep] = useState(1);
  const content = (
    <div
      className={classNames(styles.auth, styles[`auth-${type}`])}
      style={{ display: visible ? 'block' : 'none' }}
    >
      <i className={styles.mask} />
      <div className={styles.main} id="auth-form">
        <div className={styles.header}>实名认证</div>
        {step === 1 && (
          <>
            <Form
              form={form}
              initialValues={{ type: [1] }}
              scrollToFirstError
              className={styles.form}
              layout="vertical"
              name="basic"
              autoComplete="off"
              validateTrigger={false}
            >
              <Form.Item label="用户类型：" name="type" valuePropName="defaultValue">
                <CheckTag data={tag} type="green" />
              </Form.Item>

              <Form.Item
                required={false}
                label="姓名"
                rules={[{ required: true, message: '请填写姓名' }]}
                name="name"
              >
                <Input placeholder="身份证上的姓名" />
              </Form.Item>
              <Form.Item
                required={false}
                label="身份证号"
                validateFirst
                rules={[
                  { required: true, message: '请填写身份证号' },
                  ({}) => ({
                    validator(_, value) {
                      if (typeValue?.[0] === 2) {
                        return Promise.resolve();
                      }
                      if (regMap.idCard.test(value)) {
                        return Promise.resolve();
                      }
                      return Promise.reject(new Error('请填写正确的身份证号'));
                    },
                  }),
                ]}
                name="idcard"
              >
                <Input placeholder="输入身份证号码" />
              </Form.Item>
              {/* {typeValue?.[0] === 1 && (
                <Form.Item
                  required={false}
                  label="银行卡号"
                  rules={[{ required: true, message: '请填写银行卡号' }]}
                  name="bankcard"
                >
                  <Input placeholder="输入银行卡号" />
                </Form.Item>
              )} */}
              {typeValue?.[0] === 2 && (
                <>
                  <div>
                    <div className="ant-col ant-form-item-label">
                      <label className="" title="身份证">
                        身份证
                      </label>
                    </div>
                    <div className={styles.idcardWrapper}>
                      <Form.Item
                        required={false}
                        label=""
                        rules={[
                          { validator: (rule, value) => validUpload(rule, value, '身份证正面') },
                        ]}
                        name="idcardFront"
                      >
                        <UploadIdCard type={1} />
                      </Form.Item>
                      <Form.Item
                        required={false}
                        label=""
                        rules={[
                          { validator: (rule, value) => validUpload(rule, value, '身份证反面') },
                        ]}
                        name="idcardBack"
                      >
                        <UploadIdCard type={2} />
                      </Form.Item>
                    </div>
                  </div>
                  <div>
                    <div className={classNames(styles.videoWrapper, 'ant-col ant-form-item-label')}>
                      <label className="" title="身份证">
                        手持身份证视频
                      </label>
                      <Popover
                        getPopupContainer={() => document.getElementById('auth-form')!}
                        overlayClassName={styles.videoTipsPopover}
                        placement="right"
                        trigger="click"
                        content={<TipsPopover />}
                      >
                        <div className={styles.tips}>
                          视频规范
                          <i className={styles.icon} />
                        </div>
                      </Popover>
                    </div>
                    <Form.Item
                      required={false}
                      label=""
                      rules={[
                        { validator: (rule, value) => validUpload(rule, value, '手持身份证视频') },
                      ]}
                      name="idcardVideo"
                    >
                      <UploadVideo />
                    </Form.Item>
                  </div>
                </>
              )}
            </Form>
            <div className={styles.footer}>
              <div className={styles.button} onClick={onClose}>
                取消
              </div>
              <div className={classNames(styles.button, styles.submit)} onClick={handleSubmit}>
                <Spin spinning={submitLoading} size="small" /> 提交
              </div>
            </div>
          </>
        )}
        {step === 2 && (
          <div className={styles.face}>
            <div className={styles.tips}>请继续扫码完成人脸认证</div>
            <img loading="lazy" src={config?.data?.qr} alt="" className={styles.qrcode} />
          </div>
        )}

        <img
          loading="lazy"
          className={styles.close}
          src={require('./images/icon-close.png')}
          alt=""
          onClick={() => onClose?.()}
        />
      </div>
    </div>
  );

  return ReactDOM.createPortal(
    // 这里可以是dom元素,也可以是react组件,还可以是react节点
    content,
    // 将传入的元素/组件/节点,挂载到container下面
    container,
  );
};

const show = (options: Pick<OriginAuthModalProps, 'data' | 'onClose' | 'onSuccess'>) => {
  const { data = [], onClose, onSuccess } = options || {};
  const container = document.createElement('div');
  container.setAttribute('id', uid() + '' + Date.now());
  document.body.appendChild(container);
  const handleClose = () => {
    onClose?.();
    ReactDOM.unmountComponentAtNode(container);
    document.body.removeChild(container);
  };
  ReactDOM.render(
    <OriginAuthModal
      data={data}
      container={container}
      visible={true}
      destroyOnClose
      onClose={handleClose}
      onSuccess={onSuccess}
    />,
    container,
  );
};

type AuthModalType = typeof OriginAuthModal & {
  show: typeof show;
};
export const AuthModal = OriginAuthModal as AuthModalType;
AuthModal.show = show;

export default AuthModal;
